package com.wanhong.springboot.ssm.framework.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.wanhong.springboot.ssm.framework.exception.BizException;
import com.wanhong.springboot.ssm.framework.exception.BizExceptionCodeEnum;


public class Result<T> {
    public static final String DEF_ERROR_MESSAGE = "系统繁忙，请稍候再试";
    public static final String HYSTRIX_ERROR_MESSAGE = "请求超时，请稍候再试";
    private static final int SUCCESS = 0;
    private static final int FAIL = -1;

    /**
     * 调用是否成功标识，0：成功，-1:系统繁忙，此时请开发者稍候再试 详情见[ExceptionCode]
     */
    private int code;

    /**
     * 调用结果
     */
    private T data;

    /**
     * 结果消息，如果调用成功，消息通常为空T
     */
    private String msg = "ok";

    private Result() {
        super();
    }

    public Result(int code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    /**
     * 请求成功消息
     *
     * @param data 结果
     * @return RPC调用结果
     */
    public static <E> Result<E> success(E data) {
        return new Result<>(SUCCESS, data, "ok");
    }

    /**
     * 请求成功方法 ，data返回值，msg提示信息
     *
     * @param data 结果
     * @param msg  消息
     * @return RPC调用结果
     */
    public static <E> Result<E> success(E data, String msg) {
        return new Result<>(SUCCESS, data, msg);
    }

    /**
     * 请求失败消息
     *
     * @param msg
     * @return
     */
    public static <E> Result<E> fail(int code, String msg) {
        return new Result<>(code, null, (msg == null || msg.isEmpty()) ? DEF_ERROR_MESSAGE : msg);
    }

    public static <E> Result<E> fail(String msg) {
        return fail(FAIL, msg);
    }


    public static <E> Result<E> fail(BizExceptionCodeEnum exception) {
        if (exception == null) {
            return fail(DEF_ERROR_MESSAGE);
        }
        return new Result(exception.getCode(), null, exception.getMsg());
    }

    /**
     * 请求失败消息，根据异常类型，获取不同的提供消息
     *
     * @param throwable 异常
     * @return RPC调用结果
     */
    public static <E> Result<E> fail(Throwable throwable) {
        return fail(throwable != null ? throwable.getMessage() : DEF_ERROR_MESSAGE);
    }

    public static <E> Result<E> timeout() {
        return fail(HYSTRIX_ERROR_MESSAGE);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    /**
     * 逻辑处理是否成功
     *
     * @return 是否成功
     */
    @JsonIgnore
    public boolean isSuccess() {
        return this.code == SUCCESS;
    }

    public static <E> Result<E> failThrow(){
        if(true){
            throw new BizException(-1, DEF_ERROR_MESSAGE);
        }
        return fail(DEF_ERROR_MESSAGE);
    }

    public static <E> Result<E> failThrow(String msg){
        if(true){
            throw new BizException(-1, msg);
        }
        return fail(msg);
    }

    public static <E> Result<E> failThrow(int code, String msg){
        if(true){
            throw new BizException(code , msg);
        }
        return fail(code, msg);
    }

}
